package com.encapi.framework.wrapper.response;

import com.encapi.framework.core.CryptManager;
import com.encapi.framework.wrapper.ResponseDataWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

public abstract class AbstractResponseDataWrapper<T> implements ResponseDataWrapper<T> {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    private CryptManager cryptManager;

    @Override
    public T wrap(T originData, MethodParameter method, MediaType mediaType,
                  ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) throws Exception
    {
        // 加密前操作
        Object needEncData = this.parseOriginData(originData);
        if (needEncData == null) {
            return originData;
        }
        // 反序列化操作
        String strNeedEncData = this.convertJson(needEncData);
        // 加密
        String encryptedData = this.encrypt(strNeedEncData, null, serverHttpResponse.getHeaders());
        // 开启调试
        if (log.isDebugEnabled()) {
            log.debug("[encapi] response body before encrypted： {}，response body after encrypted： {}", strNeedEncData, encryptedData);
        }
        // 加密后操作
        return this.wrapToEntity(originData, encryptedData);
    }


    // 需要加密的数据转成JSON字符串
    protected abstract String convertJson(Object needEncData) throws Exception;

    // 解析原始数据
    protected abstract Object parseOriginData(T originData);

    // 包装加密后的数据
    protected abstract T wrapToEntity(T originData, String encryptedData);

    /**
     * 加密解析后的字符串数据
     * @param jsonStrData 解析后字符串数据
     * @param request 请求
     * @param headers 请求头
     * @return
     */
    protected String encrypt(String jsonStrData, HttpServletRequest request, HttpHeaders headers) {
        return cryptManager.encrypt(jsonStrData, null, headers);
    }
}
